﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.IO;
using System.Collections.Generic;

/*********************************************************
 * 
 * programmer:		patrick.woolhoo@gmail.com
 * svn:				http://woolhoo-net.googlecode.com/svn/trunk/wnet/
 * class:			Valid
 * desc:			实现登录等功能
 * 
 * *******************************************************/

namespace Patrick.Custom {
	public class Valid {

		public enum AuthMethod { SESSION, COOKIE };

		public Valid() {
			//
			// TODO: 在此处添加构造函数逻辑
			//

		}

		#region 验证

		/// <summary>
		/// 后台是否登录
		/// </summary>
		/// <returns></returns>
		public static bool LoggedIn() {
			return GetAuthCredential("AdminAuth").HasKeys();
		}

		public static bool LoggedIn(string key) {
			return GetAuthCredential(key).HasKeys();
		}

		#endregion


		#region 登录

		/// <summary>
		/// 登录后台，appsettings["AuthMethod"]{session, cookie} 可以控制登录方式
		/// </summary>
		/// <param name="identity">登录内容</param>
		public static void LogIn(NameValueCollection identity) {
			LogIn(identity, "AdminAuth");
		}

		public static void LogIn(NameValueCollection identity, string key) {
			string authMethod = ConfigurationManager.AppSettings["AuthMethod"];
			if (String.IsNullOrEmpty(authMethod)) LogInBySession(identity, key);
			else if (authMethod.ToLower() == "session") LogInBySession(identity, key);
			else if (authMethod.ToLower() == "cookie") LogInByCookie(identity, key);
		}



		/// <summary>
		/// 通过 session 方式登录
		/// </summary>
		public static void LogInBySession(NameValueCollection identity, string key) {
			string IdStr = GetIdStr(identity);
			SymmetricMethod sm = new SymmetricMethod();
			string auth = sm.Encrypto(IdStr.ToString());
			HttpContext.Current.Session[key] = auth;
		}



		/// <summary>
		/// 通过 cookie 方式登录
		/// </summary>
		public static void LogInByCookie(NameValueCollection identity, string key) {
			string IdStr = GetIdStr(identity);
			SymmetricMethod sm = new SymmetricMethod();
			string auth = sm.Encrypto(IdStr.ToString());
			HttpContext.Current.Response.Cookies[HttpContext.Current.Request.MapPath("~")][key] = auth;
		}

		#endregion


		#region 退出

		/// <summary>
		/// 自动检测验证方式
		/// </summary>
		public static void Logout() {
			Logout("AdminAuth");
		}

		public static void Logout(string key) {
			string authMethod = ConfigurationManager.AppSettings["AuthMethod"];
			if (String.IsNullOrEmpty(authMethod)) LogoutBySession(key);
			else if (authMethod.ToLower() == "session") LogoutBySession(key);
			else if (authMethod.ToLower() == "cookie") LogoutByCookie(key);
		}


		/// <summary>
		/// 指定验证方式
		/// </summary>
		/// <param name="method"></param>
		public static void Logout(AuthMethod method) {
			Logout(method, "AdminAuth");
		}

		public static void Logout(AuthMethod method, string key) {
			switch (method) {
				case AuthMethod.SESSION:
					LogoutBySession(key);
					break;
				case AuthMethod.COOKIE:
					LogoutByCookie(key);
					break;
			}
		}



		public static void LogoutBySession(string key) {
			HttpContext.Current.Session.Remove(key);
		}

		public static void LogoutByCookie(string key) {
			HttpCookie myCookie = HttpContext.Current.Request.Cookies[HttpContext.Current.Request.MapPath("~")];
			myCookie.Values.Remove(key);
			HttpContext.Current.Response.Cookies.Add(myCookie);
		}

		#endregion


		#region 得到登录凭证

		/// <summary>
		/// 得到登录凭证
		/// </summary>
		/// <returns></returns>
		public static NameValueCollection GetAuthCredential() {
			return GetAuthCredential("AdminAuth");
		}

		public static NameValueCollection GetAuthCredential(string key) {
			string authMethod = ConfigurationManager.AppSettings["AuthMethod"];
			if (String.IsNullOrEmpty(authMethod)) return GetAuthCredentialBySession(key);
			else if (authMethod.ToLower() == "session") return GetAuthCredentialBySession(key);
			else return GetAuthCredentialByCookie(key);
		}



		/// <summary>
		/// 得到登录凭证
		/// </summary>
		/// <returns></returns>
		public static NameValueCollection GetAuthCredentialBySession(string key) {
			NameValueCollection ret = new NameValueCollection();
			string auth = (string)HttpContext.Current.Session[key];
			string IdStr = null;
			string[] temp1 = null;
			string[] temp2 = null;

			if (!String.IsNullOrEmpty(auth)) {
				SymmetricMethod sm = new SymmetricMethod();
				IdStr = sm.Decrypto(auth);
				temp1 = IdStr.Split(new char[] { '\n' });
				foreach (string str1 in temp1) {
					temp2 = str1.Split(new char[] { '\t' });
					ret.Add(temp2[0], temp2[1]);
				}
			}
			return ret;
		}



		/// <summary>
		/// 得到登录凭证
		/// </summary>
		/// <returns></returns>
		public static NameValueCollection GetAuthCredentialByCookie(string key) {
			NameValueCollection ret = new NameValueCollection();
			string authEncoded = null;
			if (HttpContext.Current.Request.Cookies[HttpContext.Current.Request.MapPath("~")] != null)
				authEncoded = HttpContext.Current.Request.Cookies[HttpContext.Current.Request.MapPath("~")][key];
			string IdStr = null;
			string[] temp1 = null;
			string[] temp2 = null;

			if (!String.IsNullOrEmpty(authEncoded)) {
				SymmetricMethod sm = new SymmetricMethod();
				IdStr = sm.Decrypto(authEncoded);
				temp1 = IdStr.Split(new char[] { '\n' });
				foreach (string str1 in temp1) {
					temp2 = str1.Split(new char[] { '\t' });
					ret.Add(temp2[0], temp2[1]);
				}
			}
			return ret;
		}

		#endregion


		/// <summary>
		/// 将登录内容转化为字符串，登录内容中不能包含制表符和换行符
		/// </summary>
		/// <param name="identity"></param>
		/// <returns></returns>
		public static string GetIdStr(NameValueCollection identity) {
			StringBuilder IdStr = new StringBuilder();
			foreach (string key in identity.AllKeys) {
				IdStr.Append(key + "\t" + identity[key] + "\n");
			}
			if (IdStr.Length > 0) IdStr.Remove(IdStr.Length - 1, 1);
			return IdStr.ToString();
		}



		#region 确定访问权限

		/// <summary>
		/// 确定当前用户是否有访问权限，每个应用应该自定义HaveAccessRight（）
		/// </summary>
		/// <returns></returns>
		public static bool HaveAccessRight() {
			return HaveAccessRight("AdminAuth");
		}

		public static bool HaveAccessRight(string key) {
			if (!LoggedIn(key)) return false;

			NameValueCollection authCred = GetAuthCredential(key);
			bool siAccess = true;
			Control ctrl = new Control();

			string filepath = HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"].ToLower();
			string filename = Path.GetFileName(filepath);
			string pathname = Path.GetFileName(Path.GetDirectoryName(filepath)).ToLower();
			string adminpath = ctrl.ResolveUrl(ConfigurationManager.AppSettings["AdminPath"]).ToLower();
			string adminpathname = Path.GetFileName(adminpath);
			bool inAdmin = adminpath == filepath.Substring(0, adminpath.Length);



			if (inAdmin) {
				// 非管理员，信息管理员级别不可操作后台
				if (Convert.ToInt32(authCred["user_level"]) > 2) {
					Js.Alert("您没有此权限！", false);
					Js.Back(true);
					HttpContext.Current.Response.End();
					return false;
				}


				// 非管理员不可操作帐号，用户，会员
				List<string> adminOnly = new List<string>();
				adminOnly.Add("users");
				adminOnly.Add("trainers");
				adminOnly.Add("members");

				if (Convert.ToInt32(authCred["user_level"]) > 1 && adminOnly.Contains(pathname)) {
					Js.Alert("您没有此权限！", false);
					Js.Back(true);
					HttpContext.Current.Response.End();
					return false;
				}
			}



			List<string> siFiles = new List<string>();
			siFiles.Add("si_products.aspx");
			siFiles.Add("si_product.aspx");
			siFiles.Add("si_solutions.aspx");
			siFiles.Add("si_solution.aspx");
			siFiles.Add("si_faq.aspx");
			siFiles.Add("si_posts.aspx");
			siFiles.Add("si_post.aspx");
			siFiles.Add("si_dopost.aspx");
			siFiles.Add("si_reply.aspx");
			siFiles.Add("si_sales_info.aspx");
			// 如果用户级别低于信息管理员则根据所在公司的情况确定是否可以访问si专区
			if (Convert.ToInt32(authCred["user_level"]) > 2) {
				Model mUsers = new Model("users");
				int partnerId = 0;
				object obj = mUsers.Field("partner_id", "[id] = " + authCred["user_id"]);
				if (obj != null) partnerId = Convert.ToInt32(obj);

				Model mPartners = new Model("partners");
				siAccess = Convert.ToBoolean(mPartners.Field("si_access", "[id] = " + partnerId));
			}

			if (siFiles.Contains(filename) && !siAccess) return false;

			return true;
		}

		#endregion

	}
}